package com.example.demo.mapper;

import com.example.demo.model.entity.user.User;
import com.example.demo.model.enums.UserStatus;
import com.example.demo.model.enums.UserTypeEnum;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.type.EnumTypeHandler;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

@Mapper
public interface UserMapper {
    // 定义公共查询字段常量，提高代码可维护性
    String USER_FIELDS = "user_id as userId, " +
            "username, " +
            "password, " +
            "name, " +
            "email, " +
            "phone, " +
            "avatar, " +
            "user_type as userType, " +
            "status, " +
            "create_time as createTime, " +
            "update_time as updateTime ";

    /**
     * 根据用户名查找用户信息
     * @param username 用户名
     * @return 包含用户信息的 Optional 对象，如果未找到则返回空的 Optional
     */
    @Select("SELECT * FROM sys_user WHERE username = #{username}")
    @Results({
            @Result(property = "userType", column = "user_type",
                    typeHandler = UserTypeEnum.TypeHandler.class) // 使用自定义处理器
    })
    Optional<User> findByUsername(String username);

    /**
     * 根据用户ID列表批量查询用户信息
     * @param userIds 用户ID列表
     * @return 用户信息列表
     */
    @Select({
            "<script>",
            "SELECT " + USER_FIELDS + "FROM sys_user",
            "WHERE user_id IN",
            "<foreach item='id' collection='userIds' open='(' separator=',' close=')'>",
            "#{id}",
            "</foreach>",
            "</script>"
    })
    @Results({
            @Result(property = "userType", column = "user_type",
                    javaType = UserTypeEnum.class, typeHandler = EnumTypeHandler.class),
            @Result(property = "status", column = "status",
                    javaType = Integer.class)
    })
    List<User> findByUserIds(@Param("userIds") List<Long> userIds);

    /**
     * 根据邮箱查找用户信息
     * @param email 邮箱
     * @return 包含用户信息的 Optional 对象，如果未找到则返回空的 Optional
     */
    @Select("SELECT " +
            "user_id as userId, " +
            "username, " +
            "user_type as userType, " +
            "status " +
            "FROM sys_user WHERE email = #{email}")
    @Results({
            @Result(property = "userType", column = "user_type",
                    typeHandler = EnumTypeHandler.class),
            @Result(property = "status", column = "status",
                    javaType = Integer.class)
    })
    Optional<User> findByEmail(String email);

    /**
     * 插入用户信息
     * @param user 用户对象
     * @return 插入成功的记录数
     */
    @Insert("INSERT INTO sys_user (" +
            "username, password, name, email, phone, " +
            "avatar, user_type, status, create_time" +
            ") VALUES (" +
            "#{username}, #{password}, #{name}, #{email}, #{phone}, " +
            "#{avatar}, #{userType}, #{status}, #{createTime}" +
            ")")
    @Options(useGeneratedKeys = true, keyProperty = "userId", keyColumn = "user_id")
    int insert(User user);

    /**
     * 更新用户信息
     * @param user 用户对象
     * @return 更新成功的记录数
     */
    @Update("UPDATE sys_user SET " +
            "username = #{username}, " +
            "password = #{password}, " +
            "name = #{name}, " +
            "email = #{email}, " +
            "phone = #{phone}, " +
            "avatar = #{avatar}, " +
            "user_type = #{userType}, " +
            "status = #{status}, " +
            "update_time = CURRENT_TIMESTAMP " +
            "WHERE user_id = #{userId}")
    int update(User user);

    /**
     * 根据用户 ID 查找用户信息
     * @param userId 用户 ID
     * @return 包含用户信息的 Optional 对象，如果未找到则返回空的 Optional
     */
    @Select("SELECT " +
            "user_id as userId, " +
            "username, " +
            "name, " +
            "user_type as userType, " +
            "status " +
            "FROM sys_user WHERE user_id = #{userId}")
    @Results({
            @Result(property = "userType", column = "user_type",
                    typeHandler = EnumTypeHandler.class),
            @Result(property = "status", column = "status",
                    javaType = Integer.class)
    })
    Optional<User> findByUserId(Long userId);

    /**
     * 判断用户名是否已存在
     * @param username 用户名
     * @return 如果存在返回 true，否则返回 false
     */
    @Select("SELECT COUNT(*) > 0 FROM sys_user WHERE username = #{username}")
    boolean existsByUsername(String username);

    /**
     * 判断邮箱是否已存在
     * @param email 邮箱
     * @return 如果存在返回 true，否则返回 false
     */
    @Select("SELECT COUNT(*) > 0 FROM sys_user WHERE email = #{email}")
    boolean existsByEmail(String email);

    /**
     * 更新用户状态
     * @param userId 用户 ID
     * @param status 用户状态
     * @return 更新成功的记录数
     */
    @Update("UPDATE sys_user SET " +
            "status = #{status}, " +
            "update_time = CURRENT_TIMESTAMP " +
            "WHERE user_id = #{userId}")
    int updateStatus(@Param("userId") Long userId,
                     @Param("status") Integer status);

    /**
     * 分页查询用户信息（PageHelper 自动处理分页）
     * @return 用户信息列表
     */
    @Select("SELECT " + USER_FIELDS + "FROM sys_user")
    @Results({
            @Result(property = "userType", column = "user_type",
                    javaType = UserTypeEnum.class, typeHandler = EnumTypeHandler.class),
            @Result(property = "status", column = "status",
                    javaType = Integer.class)
    })
    List<User> findAll(); // 移除 offset 和 limit 参数

    /**
     * 根据用户 ID 删除用户信息
     * @param userId 用户 ID
     * @return 删除成功的记录数
     */
    @Delete("DELETE FROM sys_user WHERE user_id = #{userId}")
    int delete(Long userId);

    /**
     * 更新用户密码
     * @param userId 用户 ID
     * @param password 新密码
     * @return 更新成功的记录数
     */
    @Update("UPDATE sys_user SET password = #{password}, update_time = CURRENT_TIMESTAMP WHERE user_id = #{userId}")
    int updatePassword(@Param("userId") Long userId, @Param("password") String password);

    /**
     * 统计用户总数
     * @return 用户总数
     */
    @Select("SELECT COUNT(*) FROM sys_user")
    int countAll();

    /**
     * 根据用户名或姓名关键字搜索用户信息
     * @param keyword 关键字
     * @return 用户信息列表
     */
    @Select("SELECT " +
            "user_id as userId, " +
            "username, " +
            "name, " +
            "user_type as userType, " +
            "status " +
            "FROM sys_user WHERE username LIKE CONCAT('%', #{keyword}, '%') OR name LIKE CONCAT('%', #{keyword}, '%')")
    @Results({
            @Result(property = "userType", column = "user_type",
                    typeHandler = EnumTypeHandler.class),
            @Result(property = "status", column = "status",
                    javaType = Integer.class)
    })
    List<User> searchByUsernameOrName(String keyword);
}